#!/usr/bin/env python3
import yaml
from pathlib import Path


class ServerConfigTimeout:
    connect: int
    read: int
    no_data: int


class ServerConfig:
    host: str
    port: int
    timeouts: ServerConfigTimeout = ServerConfigTimeout()
    chunk_size: int
    max_connections: int
    user_agent: str


class LogConfig:
    directory: str
    level: str
    retention_days: int


class CacheConfig:
    enabled: bool
    directory: str


class AppConfig:
    server: ServerConfig = ServerConfig()
    mirrors: list
    cache: CacheConfig = CacheConfig()
    log: LogConfig = LogConfig()


class ConfigManager:
    def __init__(self, config_file='config.yaml'):
        self.config_file = Path(config_file)
        self.config: AppConfig = AppConfig()
        self.load_config()

    def load_config(self):
        """加载并验证配置文件"""
        with open(self.config_file, 'r', encoding='utf-8') as f:
            conf = yaml.safe_load(f)

        self._validate_config(conf)

        self.config.mirrors = conf['proxy_mirrors']

        server_conf = conf['server']
        self.config.server.host = server_conf['host']
        self.config.server.port = server_conf['port']
        self.config.server.chunk_size = server_conf['chunk_size']
        self.config.server.max_connections = server_conf['max_connections']
        self.config.server.user_agent = server_conf['user_agent']
        self.config.server.timeouts.connect = server_conf['timeouts']['connect']
        self.config.server.timeouts.read = server_conf['timeouts']['read']
        self.config.server.timeouts.no_data = server_conf['timeouts']['no_data']

        cache_conf = conf.get('cache', {'enabled': False, 'directory': './cache'})
        self.config.cache.enabled = cache_conf['enabled']
        self.config.cache.directory = cache_conf['directory']

        log_conf = conf.get('log', {
            'directory': './logs',
            'level': 'INFO',
            'retention_days': 7
        })
        self.config.log.directory = log_conf['directory']
        self.config.log.level = log_conf['level']
        self.config.log.retention_days = log_conf['retention_days']

    def _validate_config(self, conf):
        """验证配置内容"""
        required_fields = [
            'proxy_mirrors',
            'server.host',
            'server.port',
            'server.timeouts.connect',
            'server.timeouts.read',
            'server.timeouts.no_data',
            'server.chunk_size',
            'server.max_connections'
        ]

        for field in required_fields:
            parts = field.split('.')
            current = conf
            for part in parts:
                if part not in current:
                    raise ValueError(f"Missing required config field: {field}")
                current = current[part]

        if not isinstance(conf['server']['port'], int) or not (1 <= conf['server']['port'] <= 65535):
            raise ValueError("Invalid port number")
        if conf['server']['chunk_size'] <= 0:
            raise ValueError("Chunk size must be positive")
        if conf['server']['max_connections'] <= 0:
            raise ValueError("Max connections must be positive")

        if conf['server']['timeouts']['connect'] <= 0:
            raise ValueError("Connect timeout must be positive")
        if conf['server']['timeouts']['read'] <= 0:
            raise ValueError("Read timeout must be positive")
        if conf['server']['timeouts']['no_data'] <= 0:
            raise ValueError("No data timeout must be positive")

        # 验证日志配置
        log_conf = conf.get('log', {})
        if not log_conf.get('directory', '').strip():
            raise ValueError("Log directory must be specified")
        if log_conf.get('level', 'INFO') not in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'):
            raise ValueError("Invalid log level")
        if not isinstance(log_conf.get('retention_days', 7), int) or log_conf.get('retention_days', 7) <= 0:
            raise ValueError("Log retention days must be positive integer")

        for path, url in conf['proxy_mirrors'].items():
            if not path.startswith('/') or not path.endswith('/'):
                raise ValueError(f"Proxy path must start and end with '/': {path}")
            if not url.startswith('http://') and not url.startswith('https://'):
                raise ValueError(f"Invalid mirror URL: {url}")


# 全局配置实例
try:
    CONFIG = ConfigManager().config
except Exception as e:
    print(f"Configuration error: {str(e)}")
    import sys

    sys.exit(1)
